#include "OpenGLTexture.h"

#include "OpenGLBase.h"

#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>

namespace SE
{
	OpenGLTexture::OpenGLTexture(const String& filePath)
		: mPath(filePath), mIsLoaded(false), mTextureBuffer(nullptr)
	{
		SE_PROFILE_FUNCTION();

		I32 width, height, channels;
		stbi_set_flip_vertically_on_load(0);

		void* buffer = nullptr;
		{
			SE_PROFILE_SCOPE("stbi_load - OpenGLTexture2D::OpenGLTexture2D(const String&)");
			buffer = stbi_load(filePath.data(), &width, &height, &channels, 0);
		}

		if (buffer)
		{
			mIsLoaded = true;
			
			auto internalFormat = channels == 4 ? RenderInternalFormat::RGBA8 : RenderInternalFormat::RGB8;

			U32 size[] = { U32(width), U32(height) };
			mTextureBuffer = TextureBuffer::Create(
				2,
				size,
				internalFormat,
				TextureBuffer::WrapMode::Repeat,
				TextureBuffer::MinFilterMode::Linear,
				TextureBuffer::MagFilterMode::Linear,
				false,
				false);
			mTextureBuffer->setBuffer(buffer, size, 2);

			stbi_image_free(buffer);
		}
		else
			LOG_ERROR("Could not load texture: {}", filePath);
	}

	OpenGLTexture::OpenGLTexture(const Ref<TextureBuffer>& textureBuffer)
		: mPath(""), mIsLoaded(false), mTextureBuffer(textureBuffer)
	{
	}

	OpenGLTexture::~OpenGLTexture()
	{
	}

	U32 OpenGLTexture::getRenderID() const
	{
		return mTextureBuffer->getRenderID();
	}

	const String& OpenGLTexture::getPath() const
	{
		return mPath;
	}

	U32 OpenGLTexture::getSize(const U32 dimension) const
	{
		return mTextureBuffer->getBufferSize(dimension);
	}

	Boolean OpenGLTexture::isLoaded() const
	{
		return mIsLoaded;
	}

	void OpenGLTexture::bind(const U32 slot) const
	{
		return mTextureBuffer->bind(slot);
	}

	Boolean OpenGLTexture::operator==(const Texture& other) const
	{
		return mTextureBuffer->getRenderID() == other.getRenderID();
	}
} // !namespace SE